﻿package solver {
	import fl.transitions.easing.Regular;
	import fl.transitions.Tween;
	import flash.display.MovieClip;
	import hanoi.Disc;
	import hanoi.Hanoi;
	import hanoi.HanoiEvent;
	import hanoi.Move;
	import hanoi.Tower;
	
	/**
	 * Movieclip para visualizar una sesión de juego de las torres de hanoi.
	 */
	public class HanoiViewer extends MovieClip {
		/**
		 * La duración en segundos de cada movida.
		 */
		public static const MOVE_DURATION:Number = 0.5;
		
		/**
		 * Instancia singleton.
		 */
		private static var _instance:HanoiViewer;
		
		/**
		 * Instancia singleton.
		 */
		public static function get instance():HanoiViewer {
			return _instance;
		}
		
		/**
		 * Movieclip para la primera torre.
		 */
		public var tower1:MovieClip;
		/**
		 * Movieclip para la segunda torre.
		 */
		public var tower2:MovieClip;
		/**
		 * Movieclip para la tercer torre.
		 */
		public var tower3:MovieClip;
		
		/**
		 * Movieclip para el primer disco.
		 */
		public var disc1:MovieClip;
		/**
		 * Movieclip para el segundo disco.
		 */
		public var disc2:MovieClip;
		/**
		 * Movieclip para el tercer disco.
		 */
		public var disc3:MovieClip;
		/**
		 * Movieclip para el cuarto disco.
		 */
		public var disc4:MovieClip;
		/**
		 * Movieclip para el quinto disco.
		 */
		public var disc5:MovieClip;
		/**
		 * Movieclip para el sexto disco.
		 */
		public var disc6:MovieClip;
		/**
		 * Movieclip para el septimo disco.
		 */
		public var disc7:MovieClip;
		/**
		 * Movieclip para el octavo disco.
		 */
		public var disc8:MovieClip;
		/**
		 * Movieclip para el noveno disco.
		 */
		public var disc9:MovieClip;
		/**
		 * Movieclip para el decimo disco.
		 */
		public var disc10:MovieClip;
		
		/**
		 * Juego de las torres de hanoi visualizado en este movieclip.
		 */
		private var _game:Hanoi;
		
		/**
		 * Constructor.
		 * Se presupone existe solo una instancia en el stage.
		 * @private
		 */
		public function HanoiViewer() {
			super();
			_instance = this;
			_game = new Hanoi(10);
			_game.addEventListener(HanoiEvent.DISC_MOVED, discMoved);
		}
		
		/**
		 * Juego de las torres de hanoi visualizado en este movieclip.
		 */
		public function get game():Hanoi {
			return _game;
		}
		
		/**
		 * Listener del evento de movida de un disco.
		 * @param event El evento ocurrido.
		 */
		private function discMoved(event:HanoiEvent):void {
			var disc:MovieClip = getDiscAsset(event.disc);
			var tower:MovieClip = getTowerAsset(event.to);
			new Tween(disc, "x", Regular.easeInOut, disc.x, tower.x, MOVE_DURATION, true);
		}
		
		/**
		 * Obtiene el movieclip correspondiente a una torre.
		 * @param tower La torre en el juego.
		 * @return El movieclip para dicha torre.
		 */
		private function getTowerAsset(tower:Tower):MovieClip {
			switch (Move.getTowerId(game, tower)) {
				case Move.FIRST_TOWER: return tower1;
				case Move.SECOND_TOWER: return tower2;
				case Move.THIRD_TOWER: return tower3;
				default: return null;
			}
		}
		
		/**
		 * Obtiene el movieclip correspondiente a un disco.
		 * @param disc El disco en el juego.
		 * @return El movieclip para dicha disco.
		 */
		private function getDiscAsset(disc:Disc):MovieClip {
			switch (disc.size) {
				case 1: return disc1;
				case 2: return disc2;
				case 3: return disc3;
				case 4: return disc4;
				case 5: return disc5;
				case 6: return disc6;
				case 7: return disc7;
				case 8: return disc8;
				case 9: return disc9;
				case 10: return disc10;
				default: return null;
			}
		}
	}
}
